package org.boulderfoodrescue.webapp.client.pickups;

import java.util.LinkedList;
import java.util.List;

import org.boulderfoodrescue.webapp.client.Presenter;
import org.boulderfoodrescue.webapp.client.events.DonorInfoUpdatedEvent;
import org.boulderfoodrescue.webapp.client.events.DonorInfoUpdatedHandler;
import org.boulderfoodrescue.webapp.client.events.OneTimeEventUpdatedEvent;
import org.boulderfoodrescue.webapp.client.events.OneTimeEventUpdatedHandler;
import org.boulderfoodrescue.webapp.client.events.PickupUpdatedEvent;
import org.boulderfoodrescue.webapp.client.events.PickupUpdatedHandler;
import org.boulderfoodrescue.webapp.client.events.RecipientInfoUpdatedEvent;
import org.boulderfoodrescue.webapp.client.events.RecipientInfoUpdatedHandler;
import org.boulderfoodrescue.webapp.client.events.RecurringEventUpdatedEvent;
import org.boulderfoodrescue.webapp.client.events.RecurringEventUpdatedHandler;
import org.boulderfoodrescue.webapp.client.events.UsersListUpdatedEvent;
import org.boulderfoodrescue.webapp.client.events.UsersListUpdatedHandler;
import org.boulderfoodrescue.webapp.client.managers.LocationInfoManager;
import org.boulderfoodrescue.webapp.client.managers.PickupManager;
import org.boulderfoodrescue.webapp.client.managers.UserAccountManager;
import org.boulderfoodrescue.webapp.client.pickups.enterpickupreport.EnterPickupReportsView;
import org.boulderfoodrescue.webapp.client.pickups.mypickups.MyPickupsView;
import org.boulderfoodrescue.webapp.client.pickups.newpickup.NewPickupView;
import org.boulderfoodrescue.webapp.shared.Location;
import org.boulderfoodrescue.webapp.shared.Pickup;
import org.boulderfoodrescue.webapp.shared.UserAccountDetails;

import com.google.gwt.event.shared.EventBus;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Widget;

public class PickupPresenter implements Presenter, PickupInterface{
	private EventBus eventBus;
	private PickupView mainView;
	private NewPickupView newPickupView;
	private MyPickupsView myPickupsView;
	private EnterPickupReportsView pickupReportsView;
	private PickupTable table;
	private FlowPanel container = new FlowPanel();

	private List<Location> donors = new LinkedList<Location>();
	private List<Location> recipients = new LinkedList<Location>();
	private List<UserAccountDetails> volunteers = new LinkedList<UserAccountDetails>();

	public PickupPresenter(EventBus eventBus, String token)
	{
		newPickupView = new NewPickupView(this);
		myPickupsView = new MyPickupsView();
		pickupReportsView = new EnterPickupReportsView();
		table = new PickupTable(this);
		mainView = new PickupView(table, this);
		container.add(mainView);

		this.eventBus = eventBus;
		bind();

		List<Location> tempDonors = LocationInfoManager.getDonorList();
		List<Location> tempRecipients = LocationInfoManager.getRecipientList();
		List<UserAccountDetails> tempVolunteers = UserAccountManager.getAccountUsers();

		if(tempDonors != null)
			donors.addAll(tempDonors);
		if(tempRecipients != null)
			recipients.addAll(tempRecipients);
		if(tempVolunteers != null)
			volunteers.addAll(tempVolunteers);

		newPickupView.setDonorsList(donors);
		newPickupView.setRecipientList(recipients);
		newPickupView.setVolunteerList(volunteers);

		List<Pickup> pickups = PickupManager.getPickups();
		if(pickups != null){
			for(Pickup p : pickups){
				mainView.addPickup(p);
				pickupReportsView.addPickup(p);
			}
		}
		
		if(token.equals("pickupsMyPickups")){
			container.clear();
			container.add(myPickupsView);
		} else if(token.equals("pickupsEnterPickupReport")){
			container.clear();
			container.add(pickupReportsView);
		} else if(token.equals("pickupsNewPickup")){
			onNewPickupButtonClick();
		}
	}

	private void bind()
	{
		eventBus.addHandler(DonorInfoUpdatedEvent.getType(), 
				new DonorInfoUpdatedHandler(){
			@Override
			public void onDonorAdded(DonorInfoUpdatedEvent event) {
				donors.add(event.getValue());
				newPickupView.setDonorsList(donors);
			}
			@Override
			public void onDonorRemoved(DonorInfoUpdatedEvent event) {
				donors.remove(event.getValue());
				newPickupView.setDonorsList(donors);
			}
			@Override
			public void onDonorUpdated(DonorInfoUpdatedEvent event) {
				table.refreshTable();
				newPickupView.setDonorsList(donors);
			}
		});
		eventBus.addHandler(RecipientInfoUpdatedEvent.getType(), 
				new RecipientInfoUpdatedHandler(){
			@Override
			public void onRecipientAdded(RecipientInfoUpdatedEvent event) {
				recipients.add(event.getValue());
				newPickupView.setRecipientList(recipients);
			}
			@Override
			public void onRecipientRemoved(RecipientInfoUpdatedEvent event) {
				recipients.remove(event.getValue());
				newPickupView.setRecipientList(recipients);
			}
			@Override
			public void onRecipientUpdated(RecipientInfoUpdatedEvent event) {
				table.refreshTable();
				newPickupView.setRecipientList(recipients);
			}
		});
		eventBus.addHandler(UsersListUpdatedEvent.getType(), 
				new UsersListUpdatedHandler(){
			@Override
			public void onUserAdded(UsersListUpdatedEvent event) {
				volunteers.add(event.getValue());
				newPickupView.setVolunteerList(volunteers);
			}
			@Override
			public void onUserUpdated(UsersListUpdatedEvent event) {
				volunteers.remove(event.getValue());
				newPickupView.setVolunteerList(volunteers);
			}
			@Override
			public void onUserRemoved(UsersListUpdatedEvent event) {
				table.refreshTable();
				newPickupView.setVolunteerList(volunteers);
			}
			@Override
			public void onUserAddFailed(UsersListUpdatedEvent event) {
				// TODO Auto-generated method stub
			}
		});

		eventBus.addHandler(OneTimeEventUpdatedEvent.getType(),
				new OneTimeEventUpdatedHandler(){
			@Override
			public void onOneTimeEventAdded(OneTimeEventUpdatedEvent event) {
				newPickupView.addTimeSlot(event.getValue().getLocationKey(), event.getValue());
			}
			@Override
			public void onOneTimeEventUpdated(OneTimeEventUpdatedEvent event) {
				// TODO Auto-generated method stub
			}
			@Override
			public void onOneTimeEventRemoved(OneTimeEventUpdatedEvent event) {
				// TODO Auto-generated method stub
			}
		});
		eventBus.addHandler(RecurringEventUpdatedEvent.getType(), 
				new RecurringEventUpdatedHandler(){
			@Override
			public void onRecurringEventAdded(
					RecurringEventUpdatedEvent event) {
				newPickupView.addTimeSlot(event.getValue().getLocationKey(), event.getValue());
			}
			@Override
			public void onRecurringEventUpdated(
					RecurringEventUpdatedEvent event) {
				// TODO Auto-generated method stub
			}
			@Override
			public void onRecurringEventRemoved(
					RecurringEventUpdatedEvent event) {
				// TODO Auto-generated method stub
			}
		});
		eventBus.addHandler(PickupUpdatedEvent.getType(), 
				new PickupUpdatedHandler(){
			@Override
			public void onPickupAdded(PickupUpdatedEvent event) {
				mainView.addPickup(event.getValue());
				pickupReportsView.addPickup(event.getValue());
			}
			@Override
			public void onPickupUpdated(PickupUpdatedEvent event) {
				mainView.refresh();
			}
			@Override
			public void onPickupRemoved(PickupUpdatedEvent event) {
				// TODO Auto-generated method stub
			}
		});
	}

	@Override
	public Widget getWidget() {
		return container;
	}

	@Override
	public void onNewPickupButtonClick() {
		container.clear();
		container.add(newPickupView);
		newPickupView.clear();
		if(!History.getToken().equals("pickupsNewPickup"))
			History.newItem("pickupsNewPickup", false);
	}

	@Override
	public void onNewPickupCancel() {
		container.clear();
		container.add(mainView);
	}

	@Override
	public void onNewPickupSave(Pickup pickup) {
		container.clear();
		container.add(mainView);
		PickupManager.savePickup(pickup);
		History.newItem("pickups", false);

	}

	@Override
	public void onEditPickup(Pickup object) {
		container.clear();
		container.add(newPickupView);
		newPickupView.clear();
		newPickupView.setPickup(object);
		History.newItem("pickupsNewPickup", false);
	}

}
